﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using DataLayer.DummaDTO;
using Common.DTO;
using RSP_Logic.Enum;
using Common.DTO.ihopplockDTO;

namespace DataLayer
{
    /// <summary>
    /// Reads information from the Database
    /// </summary>
    [Obsolete("Använd RepositoryBase istället! /Oskar")]
    public static class GetDBInfo
    {
       //public static List<GameType> GetGameListInfoDb()
       //{
       //    var entities = new GameDbEntities();
       //    var gameTypes = entities.GameType.ToList();

       //    return Factory.CreateListOfGameType(gameTypes);

       //}

       ///// <summary>
       ///// Gets all the players in the Db
       ///// </summary>
       ///// <returns>List of Player Objects</returns>
       //public static List<Player> GetAllPlayers()
       //{
       //    var entities = new GameDbEntities();
       //    var players = entities.Player.ToList();

       //    return Factory.CreateListOfPlayers(players);
       //}

       ///// <summary>
       ///// Returns a player by Id
       ///// </summary>
       ///// <param name="playerId"></param>
       ///// <returns>Spelare</returns>
       //public static Player GetPlayerById(int playerId)
       //{
       //    try
       //    {
       //        var entities = new GameDbEntities();
       //        var player = entities.Player.FirstOrDefault(s => s.ID == playerId);
               
       //        return Factory.CreatePlayer(player);
       //    }
       //    catch
       //    {
       //        return null;
       //    }
       //}

       //public static int GetOpponentIdByGameId(int gameId, int playerId)
       //{
       //    try
       //    {
       //        var entities = new GameDbEntities();
       //        var opponent = entities.PlayerGame.FirstOrDefault(x => x.GameID == gameId && x.PlayerID != playerId);
               
       //        return opponent.PlayerID;
       //    }
       //    catch (Exception)
       //    {             
       //        throw;
       //    }
       //}

       /// <summary>
       /// Get the current Game type
       /// </summary>
       /// <param name="gameID">Gametype ID</param>
       /// <returns>Return GameType</returns>
       public static GameType GetGameTypeById(int gameTypeId)
       {
           try
           {
               var entities = new GameDbEntities();
               var gameType = entities.GameType.Where(g => g.ID == gameTypeId).SingleOrDefault();
               
               return Factory.CreateGameType(gameType);
           }
           catch
           {
               return null;
           }
       }

       ///// <summary>
       ///// Determine the Winner of a Round
       ///// </summary>
       ///// <param name="playerChoices">Players One/Two choice</param>
       ///// <returns>Players id who won the round</returns>
       //public static int DetermineRoundWinner(List<PlayerChoiceEntity> playerChoices)
       //{
       //    var playerOne = playerChoices[0];
       //    var playerTwo = playerChoices[1];

       //    // If players have chosen the same hand its a draw
       //    if (playerOne.Choice == playerTwo.Choice)
       //    {
       //        return -1;
       //    }

       //    switch (playerOne.Choice)
       //    {
       //        case (int)ChoiceEnum.Rock:
       //            return playerTwo.Choice == (int)ChoiceEnum.Scissor ? playerOne.PlayerID : playerTwo.PlayerID;
       //        case (int)ChoiceEnum.Scissor:
       //            return playerTwo.Choice == (int)ChoiceEnum.Paper ? playerOne.PlayerID : playerTwo.PlayerID;
       //        case (int)ChoiceEnum.Paper:
       //            return playerTwo.Choice == (int)ChoiceEnum.Rock ? playerOne.PlayerID : playerTwo.PlayerID;
       //        default:
       //            break;
       //    }

       //    return -1;
       //}

       ///// <summary>
       ///// Determine the Winner of a Round
       ///// </summary>
       ///// <param name="playerChoices">Players One/Two choice</param>
       ///// <returns>Player who won the round</returns>
       //public static Player DetermineRoundWinnerPlayer(List<PlayerChoiceEntity> playerChoices)
       //{
       //    var playerOne = playerChoices[0];
       //    var playerTwo = playerChoices[1];

       //    // If players have chosen the same hand its a draw
       //    if (playerOne.Choice == playerTwo.Choice)
       //    {
       //        return null;
       //    }

       //    switch (playerOne.Choice)
       //    {
       //        case (int)ChoiceEnum.Rock:
       //            return playerTwo.Choice == (int)ChoiceEnum.Scissor ? GetPlayerById(playerOne.PlayerID) : GetPlayerById(playerTwo.PlayerID);
       //        case (int)ChoiceEnum.Scissor:
       //            return playerTwo.Choice == (int)ChoiceEnum.Paper ? GetPlayerById(playerOne.PlayerID) : GetPlayerById(playerTwo.PlayerID);
       //        case (int)ChoiceEnum.Paper:
       //            return playerTwo.Choice == (int)ChoiceEnum.Rock ? GetPlayerById(playerOne.PlayerID) : GetPlayerById(playerTwo.PlayerID);
       //        default:
       //            break;
       //    }

       //    return null;
       //}


       //public static Player DetermineGameWinner(int gameId)
       //{
       //    var playerChoices = new List<PlayerChoiceEntity>();
       //    var gameDb = new GameDbEntities();

       //    var gameRounds = from p in gameDb.PlayerChoice
       //                     join g in gameDb.GameRound
       //                     on p.GameRoundID equals g.ID
       //                     where g.GameID == gameId
       //                         select p;

       //    List<int> playerIds = new List<int>();
       //    int totalGameRounds = gameRounds.Count() / 2;

       //    for (int roundId = 1; roundId < totalGameRounds; roundId++)
       //    {
       //        var round = gameRounds.Where(x => x.GameRoundID == roundId).ToList();

       //        playerIds.Add(DetermineRoundWinner(round));
       //    }

       //    var playerId  = playerIds.GroupBy(item => item).OrderByDescending(g => g.Count()).Select(g => g.Key).First();

       //    return GetPlayerById(playerId);
       //}

       ///// <summary>
       ///// Login the player
       ///// </summary>
       ///// <param name="username">Players username</param>
       ///// <param name="password">Players password</param>
       ///// <returns>Returns <see cref="PLayerDto"/> with players details</returns>
       //public static Player LoginPlayer(string username, string password)
       //{
       //    var entities = new GameDbEntities();
       //    var player = entities.Player.FirstOrDefault(p => p.Name == username);

       //    if (player == null)
       //        return null;
       //    else
       //        return Factory.CreatePlayer(player);
       //}
	   
       //public static GameRound GetCurrentGameRound (int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    var gameRounds = entities.GameRound.Where(x => x.GameID == gameId).ToList();

       //    var latestDate = gameRounds.Max(x => x.Date);

       //    var currentGameRound = gameRounds.First(x => x.Date == latestDate);

       //    return new GameRound
       //    {
       //        ID = currentGameRound.ID,
       //        GameID = currentGameRound.GameID,
       //        StartDate = currentGameRound.Date ?? DateTime.Now
       //    };			
       //}
	   

       //public static List<GameRound> GetGameRounds (int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    var gameRounds = entities.GameRound.Where(x => x.ID == gameId).ToList();

       //    if (gameRounds != null)
       //    {
       //        return gameRounds.Select(x =>
       //            new GameRound
       //            {
       //                GameID = x.GameID,
       //                ID = x.ID,
       //                StartDate = x.Date ?? DateTime.Now
       //            }).ToList();
       //    }
			
       //     return null;
       //}

       public static Game GetGameById(int gameId)
       {
           try
           {
               var entities = new GameDbEntities();

               var game = entities.Game.Where(s => s.ID == gameId).FirstOrDefault();

               return new Game
               {
                   ID = game.ID,
                   GameTypeID = (int)game.GameTypeID,
                   NameOfGame = game.GameType.Name,
                   NumOfGameRoundsToPlay = (int)game.NoOfGameRounds,
                   ActiveGame = Boolean.Parse(game.ActiveGame.ToString()),
                   StartDate = DateTime.Now,
                   EndDate = game.DateEnd ?? null,
                   WinningPlayerID = game.Winner ?? null
               };
           }
           catch
           {
               return null;
           }
       }

       //public static bool AddPlayerSession(int playerId, int gameId)
       // {
       //     try
       //     {
       //         if (SaveDBInfo.AddPlayerToGame(playerId, gameId))
       //         {
       //             return true;
       //         }

       //         else
       //         return false;
       //     }
       //     catch
       //     {
       //         return false;
       //     }
       // }
       
       //public static bool MakePlayerChoice(int gameId, int playerId, int playerChoice)
       // {
       //     return SaveDBInfo.MakePlayerChoice(gameId, playerId, playerChoice);
       // }

       //public static List<Game> GetActiveGameInfoDb()
       //{
       //    var entities = new GameDbEntities();
       //    var game = entities.Game.Where(g1 => g1.ActiveGame == true);

       //    return
       //        game.Select(
       //            g2 =>
       //            new Game
       //            {
       //                NumOfGameRoundsToPlay = (int)g2.NoOfGameRounds,
       //                ID = g2.ID,
       //                GameTypeID = (int)g2.GameTypeID
       //            }).ToList();
       //}

       //public static List<Game> GetJoinableGames(int gameTypeId, int playerId)
       //{
       //    var entities = new GameDbEntities();

       //    var games = from g in entities.Game
       //               join p in entities.PlayerGame
       //               on g.ID equals p.GameID
       //               where g.GameTypeID == gameTypeId && p.PlayerID != playerId && g.Winner == null && g.ActiveGame == false
       //               select g;

       //    return
       //        games.Select(
       //            gsd =>
       //            new Game
       //            {
       //                NumOfGameRoundsToPlay = gsd.NoOfGameRounds,
       //                ID = gsd.ID,
       //                GameTypeID = (int)gsd.GameTypeID
       //            }).ToList();
       //}

       ///// <summary>
       ///// Returns players Games
       ///// </summary>
       ///// <param name="playerId">Players id</param>
       ///// <returns>Game Objects</returns>
       //public static List<GameEntity> GetPlayersGames(int playerId)
       //{
       //    var entities = new GameDbEntities();
       //    var playerGames = (from s in entities.Game
       //                        join p in entities.PlayerGame
       //                        on s.ID equals p.GameID
       //                        where p.PlayerID == playerId
       //                         select s).ToList();

       //    return playerGames;
       //}

       ///// <summary>
       ///// Returns a players active liste
       ///// </summary>
       ///// <param name="playerId">Players id</param>
       ///// <param name="gameTypeId">Id of gametype</param>
       ///// <returns>List of active Games</returns>
       //public static List<GameEntity> GetPlayersActiveGames(int playerId, int gameTypeId)
       //{
       //    var entities = new GameDbEntities();
       //    var activeSessionList = entities.Game.Where(x => x.ActiveGame && x.GameTypeID == gameTypeId).ToList();

       //    return activeSessionList;
       //}

       //// Ska verkligen NoOfGameRounds va nullable? spel som inte har omgångar kommer inte heller att leta efter antalet omgångar?
       //public static int GetTotalOfGameRounds(int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    return entities.Game.FirstOrDefault(g => g.ID == gameId).NoOfGameRounds;
       //}

       ///// <summary>
       ///// Hämtar ut hur många omgångar som spelats hittills
       ///// </summary>
       ///// <param name="gameId"></param>
       ///// <returns></returns>
       //public static int GetNumberOfPlayedGameRounds(int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    return entities.GameRound.Count(x => x.GameID == gameId);
       //}

       ///// <summary>
       ///// Returns lastest/current gameround
       ///// </summary>
       ///// <param name="gameId">Session id of game</param>
       ///// <returns>Id of round</returns>
       //public static int GetCurrentGameRoundId(int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    return entities.GameRound.Last(x => x.GameID == gameId).ID;
       //}

       ///// <summary>
       ///// Returns Player Choice
       ///// </summary>
       ///// <param name="gameRoundId">Id of gameround</param>
       ///// <returns>PlayerChoiceEntity object</returns>
       //public static PlayerChoice GetPlayerChoice(int gameRoundId)
       //{
       //    var entities = new GameDbEntities();
       //    var playerChoice = entities.PlayerChoice.First(x => x.GameRoundID == gameRoundId);

       //    return Factory.CreatePlayerChoice(playerChoice);
       //}

       ///// <summary>
       ///// Returns multiple players choice
       ///// </summary>
       ///// <param name="gameRoundId">Id of gameround</param>
       ///// <returns>List of PlayerChoiceEntity objects</returns>
       //public static List<PlayerChoice> GetPlayersChoice(int gameRoundId)
       //{
       //    var entities = new GameDbEntities();
       //    var PlayersChoice = entities.PlayerChoice.Where(x => x.GameRoundID == gameRoundId).ToList();

       //    return PlayersChoice.Select(entity => Factory.CreatePlayerChoice(entity)).ToList();
       //}

       //public static PlayerGame GetPlayerGameByGameId(int gameId)
       //{
       //    var entities = new GameDbEntities();

       //    var playerGame = entities.PlayerGame.First(x => x.GameID == gameId);

       //    return Factory.CreatePlayerGame(playerGame);
       //}

       /// <summary>
       /// Fetches all players in a specific Game
       /// 
       /// Author: Oskar (2012-02-27)
       /// </summary>
       /// <param name="gameId">ID of Game</param>
       /// <returns>List of Players</returns>
       public static List<Player> GetPlayersInGame(int gameId)
       {
           var entities = new GameDbEntities();

           var playerGames = entities.PlayerGame.Where(x => x.GameID == gameId);

           var list = new List<Player>();
           foreach (var playerGame in playerGames)
           {
               list.Add(Factory.CreatePlayer(playerGame));
           }
           return list;
       }

       //public static int GetWonRounds(int gameId, int player)
       //{
       //    var playerChoices = new List<PlayerChoiceEntity>();
       //    var entities = new GameDbEntities();

       //    var gameRounds = from p in entities.PlayerChoice
       //                     join g in entities.GameRound
       //                     on p.GameRoundID equals g.ID
       //                     where g.GameID == gameId
       //                     select p;

       //    List<int> playerIds = new List<int>();
       //    int totalGameRounds = gameRounds.Count() / 2;

       //    for (int roundId = 1; roundId < totalGameRounds; roundId++)
       //    {
       //        var round = gameRounds.Where(x => x.GameRoundID == roundId).ToList();

       //        playerIds.Add(DetermineRoundWinner(round));
       //    }

       //    return playerIds.Where(x => x == player).Count();
       //}
       //public static List<Game> GetPlayersActiveGamesList_Init(int playerID, int gameTypeId)
       // {return null;}

       //public static List<Game> GetPlayersActiveGamesList_Poll(int playerID, int gameTypeId)
       // {return null;}

       

       
    }
}
